#ifndef __cache_if_h__
#define __cache_if_h__
#pragma once
#include "types.h"


template<int n,class T>
class CPsuedoLRUCtrl
{
	static bool ok;
	static T one_mask[n],zero_mask[n];
public:

	CPsuedoLRUCtrl();

	int Oldest(T age);
	T NewAge(T age, T youngest);
};


typedef enum cache_state {
	Invalid,Valid,Modified,Exclusive,Shared
}CACHE_STATE;

template <int nLinesInBits, int nWaysInBits,int nBytesInBits,class T>
class CCache
{
	CPsuedoLRUCtrl<(1<<nWaysInBits),T> lru_ctrl;

	unsigned int nWays(){return (1<<nWaysInBits);}
	unsigned int nBytes(){return (1<<nBytesInBits);}
	unsigned int nLines(){return 1<<nLinesInBits;}
	unsigned int LineIdxMask(){return (1<<nLinesInBits)-1;}

	struct
	{
		__u32 tag;
		__u8 data[nBytesInBits];
		__u32 pa;
		__u32  state:2; //mesi
	} lines[1<<nLinesInBits][1<<nWaysInBits];

	T ages[1<<nLinesInBits];
public:
	CCache() {
		invalidate_all();
	}

	void invalidate_all();


	 bool read_byte (__u32 address,__u8 *p_dat);
	 bool read_short(__u32 address,__u16 *p_dat);
	 bool read_int(__u32 address,__u32 *p_dat);

	 bool write_byte (__u32 address,__u8  dat,__u8 *p__line_out);
	 bool write_short(__u32 address,__u16 dat,__u8 *p__line_out);
	 bool write_int(__u32 address,__u32 dat,__u8 *p__line_out);

	 bool read_line(__u32 address,__u8 * data);
	 // line state:
	 bool fill_line(__u32 address,__u8 * data,__u8 *p__line_out);

	 // line state: modified
	 bool write_line(__u32 address,__u8 * data,__u8 *p__line_out);
};




#endif //__cache_if_h__